# Image Build ***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.*** --- # Source Build and Image Packaging ## One-Click Docker Build for M1 Debian Firmware (Recommended) After the archive is extracted to `docker_env/`, it contains the Docker image, run script, and default build script. The key files in the current directory are as follows: | **File** | **Purpose** | | --- | --- | | `docker_env/docker_builder.tar` | Original archive package containing the Docker image and scripts | | `docker_env/image.tar.gz` | Docker image package. The script loads it as `quecpi-m1l1-builder-ubuntu22:latest` | | `docker_env/docker_run.sh` | One-click run entry. By default, it executes `./docker_env/build.sh` inside the container | | `docker_env/build.sh` | Default build script: executes `buildconfig`, `buildall`, and `buildpackage` | Use it as follows: ```bash cd ~/sdk/docker_env # If only docker_builder.tar is provided, extract it first: tar -xf docker_builder.tar # If this SDK directory was previously built directly on the host, # clean the old TMPDIR before switching to Docker: rm -rf ../build-qti-distro-fullstack-debug/tmp-glibc # Run the default one-click build: ./docker_run.sh ``` Default behavior of `docker_run.sh`: - If `../downloads/downloads` does not exist, the script clones `3in1_downloads_rl` and extracts the downloads package. - The container starts with `--privileged` and `--net host`, and mounts the SDK root directory into the container. - By default, it executes `./docker_env/build.sh`. A custom command can also be passed to `docker_run.sh` as the task to run inside the container. The current default `build.sh` content is shown below. It targets the M1 Debian version: ```bash source quectel_build/compile/build.sh buildconfig \ QSM200UPEMPI \ QSM200UEMPIRL1A01_BDL01BP01K0M01V01_LP5.15.153.01.001_V00 \ DEB || true buildall buildpackage ``` When the script completes successfully, the terminal should show successful `buildpackage` messages near the end, including successful QFIL package extraction and debug image copy completion: ``` build full qfil success >>>>>>>>>>>>>>>>>>>>>> UnPacking SUCCESS TARGET_DEBUG_IMG_DIR: .../quectel_build/fw/QSM200UEMPIRL1A01_BDL01BP01K0M01V01_LP5.15.153.01.001_V00_debugimg =============== debugimg copy done =============== [date] finish ``` After a successful build, firmware is output under `quectel_build/fw/` with `ProjectRev` as the prefix. Common directories are as follows: | **Directory** | **Purpose** | | --- | --- | | `QSM200UEMPIRL1A01_BDL01BP01K0M01V01_LP5.15.153.01.001_V00` | Full M1 Debian QFIL flashing package | | `QSM200UEMPIRL1A01_BDL01BP01K0M01V01_LP5.15.153.01.001_V00_ota` | OTA package, including `full_update_ext4.zip` and `target-files-ext4.zip` | | `QSM200UEMPIRL1A01_BDL01BP01K0M01V01_LP5.15.153.01.001_V00_debug` | Debug symbol directory, mainly storing `elf` files | | `QSM200UEMPIRL1A01_BDL01BP01K0M01V01_LP5.15.153.01.001_V00_debugimg` | Debug image directory, including `boot.img`, `dtbo.img`, `system.img`, and other images | Do not mix Docker builds and direct host builds with the same old `tmp-glibc`. If the SDK was built on the host first and then switched to Docker, BitBake may report: ``` Error, TMPDIR has changed location. You need to either move it back to /home/soren/QuecPi/SC200/Linux_BL01_R010/build-qti-distro-fullstack-debug/tmp-glibc or delete it and rebuild ``` This happens because the SDK path inside Docker is `/home/q1000/Linux_BL01_R010`, while the old Yocto `TMPDIR` recorded the host path `/home/soren/...`. If you are sure you want to build with Docker, delete the old `build-qti-distro-fullstack-debug/tmp-glibc` and run `./docker_run.sh` again. If you switch back to direct host builds next time, similarly let the host regenerate its own `tmp-glibc` instead of reusing the Docker-path build cache. # Platform Selection and Difference Comparison The current project uniformly loads build commands through `quectel_build/compile/build.sh`. When `buildconfig` is executed, it dispatches to the QSM200U or QSM200E platform according to `ProjectName`. The project name, chipset, MACHINE, boot platform, and package outputs differ between the two platforms. Compare the following table before modifying documents or code. | **Platform Line** | **Valid ProjectName** | | --- | --- | | **M1 / QSM200U** | `QSM200UPEMPI`, `QSM200UPNAPI`, `QSM200UPWFPI` | | **L1 / QSM200E** | `QSM200EPEMPI`, `QSM200EPNAPI`, `QSM200EPWFPI` | The currently selectable `CUST_NAME` values are the same for both platforms: `STD`, `STD_PERF`, `DBG`, `DEB`, and `DEB_PERF`. Configurations with `_PERF` select `qti-distro-fullstack-perf`; other regular configurations select `qti-distro-fullstack-debug` by default. # Initialize the Build Environment **Step 1:** After the source code has been downloaded, go to the current SDK root directory and execute the build environment script: ```bash cd ~/sdk source quectel_build/compile/build.sh ``` After execution, the commands such as `buildconfig`, `buildall`, and `buildpackage` are loaded, and the currently supported project names and customer types are printed. ``` Vaild Projects: QSM200UPEMPI QSM200UPNAPI QSM200UPWFPI QSM200EPNAPI QSM200EPWFPI QSM200EPEMPI Vaild CUST_NAME: STD STD_PERF DBG DEB DEB_PERF ``` # buildconfig Configuration Examples **ProjectRev** can theoretically be customized, but it must match the modem version. For standard versions, `CustName` must be `STD`. It is recommended to write the command in multiple lines to avoid an overly long single command. ## M1 / QSM200U Example ```bash # eMMC / current measured M1-L1 configuration buildconfig \ QSM200UPEMPI \ QSM200UPEMNARL1A01_BL01BP01K0M01V01_LP5.15.153.01.001_V01 \ STD # NA version example buildconfig \ QSM200UPNAPI \ QSM200UPNANARL1A01_BL01BP10K0M01_QPEA_LP5.15.153.01.001_V01 \ STD # WiFi-only version example buildconfig \ QSM200UPWFPI \ QSM200UPWFNARL1A01_BL01BP10K0M01_QPEA_LP5.15.153.01.001_V01 \ STD ``` ## L1 / QSM200E Example ```bash # NA version example buildconfig \ QSM200EPNAPI \ QSM200EPNADARL1A01_BL01BP10K0M01_QPEA_LP5.15.153.01.001_V01 \ STD # WiFi-only version example buildconfig \ QSM200EPWFPI \ QSM200EPWFDARL1A01_BL01BP10K0M01_QPEA_LP5.15.153.01.001_V01 \ STD # eMMC version example buildconfig \ QSM200EPEMPI \ QSM200EPEMDARL1A01_BL01BP10K0M01_QPEA_LP5.15.153.01.001_V01 \ STD ``` # Current M1 / L1 Configuration Comparison This section compares the currently measured QSM200U configuration with the corresponding QSM200E platform configuration. The QSM200U column is the M1/L1 configuration actually verified this time; the QSM200E column is the corresponding E-platform example from the same repository script prompts. `ProjectRev` still needs to be confirmed according to the actual modem version. | **Field** | **M1 / QSM200U** | **L1 / QSM200E** | **Description** | | --- | --- | --- | --- | | ProjectName | `QSM200UPEMPI` | `QSM200EPEMPI` | eMMC example project names for the two platforms | | ProjectRev | `QSM200UPEMNARL1A01_BL01BP01K0M01V01_LP5.15.153.01.001_V01` | `QSM200EPEMDARL1A01_BL01BP10K0M01_QPEA_LP5.15.153.01.001_V01` | Must match the modem version | | CustomName | `STD` | `STD` | Standard version uses STD | | Chipset | `SM6115` | `QCM2290` | Corresponding to the 200U / 200E platforms respectively | | MACHINE | `sm6115-mtp` | `qcm2290-mtp` | Yocto machine configuration | | DISTRO | `qti-distro-fullstack-debug` | `qti-distro-fullstack-debug` | Default value for regular STD builds | | Build entry | `build_200u.sh` | `build_206e.sh` | Automatically dispatched by buildconfig according to ProjectName | | BP / Boot platform | `Kamorta` / `KamortaPkg` | `Agatti` / `AgattiPkg` | Do not mix Boot/firmware paths | After the configuration succeeds, the terminal switches to the `build-qti-distro-fullstack-debug` build directory and displays the following key information: ``` DISTRO = qti-distro-fullstack-debug MACHINE = sm6115-mtp Supported image targets are: qti-robotics-image Current QUECTEL_PROJECT_NAME = QSM200UPEMPI Current QUECTEL_PROJECT_REV = QSM200UPEMNARL1A01_BL01BP01K0M01V01_LP5.15.153.01.001_V01 Current QUECTEL_CUSTOM_NAME = STD Current QUECTEL_CHIPSET_SUBTARGET = SM6115 CUSTOM_BVERSION : QSM200UPEMNARL1A01 CUSTOM_SVERSION : BL01BP01K0M01V01 CUSTOM_VERSION : 01.001V01 CUSTOM_QAPSUB : V01 ``` # AP Full Build **Step 2:** Execute the following command to perform the AP full build: ```bash buildall ``` This process takes a long time, usually 1–2 hours. After compilation is complete, if `bitbake` outputs `all succeeded`, the AP image build has succeeded. ``` NOTE: Tasks Summary: Attempted ... tasks of which ... didn't need to be rerun and all succeeded. ``` # One-Click Packaging **Step 3:** After the AP image build is complete, execute the following command to generate the QFIL flashing package, OTA package, and debug image directory: ```bash buildpackage ``` For the current measured QSM200U / `QSM200UPEMPI` configuration, `buildpackage` returns 0. Key logs are as follows: ``` build full qfil success >>>>>>>>>>>>>>>>>>>>>> UnPacking SUCCESS TARGET_DEBUG_IMG_DIR: /home/soren/QuecPi/SC200/Linux_BL01_R010/quectel_build/fw/QSM200UPEMNARL1A01_BL01BP01K0M01V01_LP5.15.153.01.001_V01_debugimg =============== debugimg copy done =============== ``` After packaging is complete, images are output to the `quectel_build/fw/` directory. Main directories for the current version are as follows: | **Directory** | **Purpose** | | --- | --- | | `QSM200UPEMNARL1A01_BL01BP01K0M01V01_LP5.15.153.01.001_V01` | Full QFIL flashing package | | `QSM200UPEMNARL1A01_BL01BP01K0M01V01_LP5.15.153.01.001_V01_ota` | OTA package, including `full_update_ext4.zip` and `target-files-ext4.zip` | | `QSM200UPEMNARL1A01_BL01BP01K0M01V01_LP5.15.153.01.001_V01_debug` | Debug symbol directory, mainly storing `elf` files | | `QSM200UPEMNARL1A01_BL01BP01K0M01V01_LP5.15.153.01.001_V01_debugimg` | Debug image directory, including `boot.img`, `dtbo.img`, `system.img`, and other images | # Image File Description The full QFIL flashing package directory contains the main images and configuration files required for flashing: **Flashing configuration files:**`rawprogram_unsparse0.xml`, `patch0.xml`, `partition.xml`, `gpt_main0.bin`, and `gpt_backup0.bin`. **AP-side images:**`boot.img`, `dtbo.img`, `system_*.img`, `userdata_*.img`, `vendor_*.img`, etc. **Modem / firmware images:**`NON-HLOS.bin`, `abl.elf`, `rpm.mbn`, `tz.mbn`, `devcfg.mbn`, `dspso.bin`, etc.